package com.sunther.document.service.impl;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunther.document.Enum.CommonEnum;
import com.sunther.document.Enum.DictEnum;
import com.sunther.document.Enum.ExportHeaderEnum;
import com.sunther.document.dao.UserDao;
import com.sunther.document.entity.ProjectHeaderEntity;
import com.sunther.document.entity.User;
import com.sunther.document.service.ProjectHeaderService;
import com.sunther.document.service.ProjectService;
import com.sunther.document.service.RoleService;
import com.sunther.document.service.UserService;
import com.sunther.document.util.ExportExcelUtil;
import com.sunther.document.util.IpUtil;
import com.sunther.document.util.RedisHelper;
import com.sunther.document.util.UserInfoUtil;
import com.sunther.idb.common.util.WebResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.sunther.document.entity.User.checkUser;

/**
 * @author csb
 * @description: TODO
 * @date 2023/5/6 9:54
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserDao,User> implements UserService{

    @Autowired
    private UserDao userDao;

    @Autowired
    private RoleService roleService;

    @Autowired
    private ProjectService projectService;

    @Autowired
    private RedisHelper redisHelper;

    @Autowired
    private ProjectHeaderService projectHeaderService;

    @Override
    public User getByName(String name) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("name",name);
        return userDao.selectOne(wrapper);
    }

    @Override
    public WebResult saveOrUpdateUser(User user, HttpServletRequest request) {
        WebResult checkUser = checkUser(user);
        if (!checkUser.isOK()){
            return checkUser;
        }

        Integer userId = UserInfoUtil.getUserId(request);

        //密码加密
        if(null == user.getId()){
            String password = DigestUtil.md5Hex(user.getPassword());
            user.setPassword(password);
        }
        //name 只能唯一
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("name",user.getName());
        if (null != user.getId()){
            wrapper.ne("id",user.getId());
        }
        List<User> list = list(wrapper);
        if (list.size() > 0) {
            return WebResult.failure("用户名已存在");
        }
        if (null == user.getId()){
            user.init(String.valueOf(userId));
        }else {
            user.modify(String.valueOf(userId));
        }

        //项目负责人，项目参与人自动加入项目
        joinProject(user);
        //译员或者管理员清除所属项目
        clearProject(user);

        saveOrUpdate(user);
        return WebResult.success("操作成功");
    }

    /**
     * 译员或者管理员清除所属项目
     * @param user
     */
    private void clearProject(User user) {
        if (Objects.equals(user.getRoleId(), DictEnum.ROLE_ADMIN.getCode()) || Objects.equals(user.getRoleId(), DictEnum.ROLE_interpreter.getCode())){
            user.setProjectId("");
            // 存在就删除
            QueryWrapper<ProjectHeaderEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id",Math.toIntExact(user.getId()));
            ProjectHeaderEntity one = projectHeaderService.getOne(wrapper);
            if (one != null) {
                projectHeaderService.removeById(one.getId());
            }
        }
    }

    /**
     * 项目参与人，负责人直接加入项目
     * @param user
     */
    private void joinProject(User user) {

        if (Objects.equals(user.getRoleId(), DictEnum.ROLE_PROJECT_LEADER.getCode()) || Objects.equals(user.getRoleId(), DictEnum.ROLE_PROJECT_PARTICIPANTS.getCode())){

            //已存在 更新
            QueryWrapper<ProjectHeaderEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id",Math.toIntExact(user.getId()));
            ProjectHeaderEntity one = projectHeaderService.getOne(wrapper);
            if (one != null) {
                one.setProjectId(user.getProjectId());
                if (Objects.equals(user.getRoleId(), DictEnum.ROLE_PROJECT_LEADER.getCode())){
                    one.setUserType(DictEnum.PROJECT_USER_TYPE_HEADER.getCode());
                }else if (Objects.equals(user.getRoleId(), DictEnum.ROLE_PROJECT_PARTICIPANTS.getCode())){
                    one.setUserType(DictEnum.PROJECT_USER_TYPE_JOIN.getCode());
                }
                projectHeaderService.updateById(one);
            }else {
                ProjectHeaderEntity entity = new ProjectHeaderEntity();
                entity.setUserId(Math.toIntExact(user.getId()));
                entity.setProjectId(user.getProjectId());
                if (Objects.equals(user.getRoleId(), DictEnum.ROLE_PROJECT_LEADER.getCode())){
                    entity.setUserType(DictEnum.PROJECT_USER_TYPE_HEADER.getCode());
                }else if (Objects.equals(user.getRoleId(), DictEnum.ROLE_PROJECT_PARTICIPANTS.getCode())){
                    entity.setUserType(DictEnum.PROJECT_USER_TYPE_JOIN.getCode());
                }
                projectHeaderService.save(entity);
            }
        }
    }

    @Override
    public Page pageList(String keyword, String projectId, Integer roleId, int pageNumber, int pageSize) {
        Page userPage = new Page(pageNumber,pageSize);
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(keyword)){
            wrapper.like("nick_name",keyword);
        }

        if (StrUtil.isNotBlank(projectId)){
            wrapper.eq("project_id",projectId);
        }
        if (null != roleId){
            wrapper.eq("role_id",roleId);
        }
        wrapper.orderByDesc("update_time");
        Page page = userDao.selectPage(userPage, wrapper);

        getText(page.getRecords());
        return page;
    }

    @Override
    public void export(String keyword, String projectId, Integer roleId, HttpServletResponse response) throws Exception {
        List<User> list = pageList(keyword, projectId, roleId, 1, 9999).getRecords();
        String title = "人员信息";
        String[] rowName = ExportHeaderEnum.USER_ROW_NAME;
        List<Object[]> dataList = new ArrayList<>();

        int i = 0;
        for (User user : list) {
            Object[] obj = new Object[rowName.length];
            obj[0] = i++;
            obj[1] = user.getName();
            obj[2] = user.getTelephone();
            obj[3] = user.getProjectText();
            obj[4] = user.getRoleText();
            dataList.add(obj);
        }

        ExportExcelUtil exportExcelUtil = new ExportExcelUtil(title, rowName, dataList, response);
        exportExcelUtil.export();
    }

    @Override
    public WebResult resetPassword(Integer id, String newPassword) {
        //返回：密码格式错误，密码支持字母、数字，区分大小写，长度8-22位。
        Pattern p = Pattern.compile("[a-zA-Z0-9]{8,22}");
        Matcher m = p.matcher(newPassword);
        boolean matches = m.matches();
        if (!matches) {
            return WebResult.failure("密码格式错误，密码支持字母、数字，区分大小写，长度8-22位。");
        }

        User user = getById(id);
        String password = DigestUtil.md5Hex(newPassword);
        user.setPassword(password);
        updateById(user);
        return WebResult.success("操作成功");
    }

    @Override
    public List<User> listByKeyword(String keyword) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(keyword)){
            wrapper.like("name",keyword);
        }
        List<User> list = list(wrapper);
        getText(list);
        return list;
    }

    @Override
    public WebResult reg(User user, String capCode, HttpServletRequest request) {
        String ipAddr = IpUtil.getIpAddr(request);
        String code = ObjectUtil.toString(redisHelper.get(CommonEnum.IMG_CAP_CODE.getCode() + ipAddr));
        if (!StrUtil.equals(capCode,code)){
            redisHelper.delete(CommonEnum.IMG_CAP_CODE.getCode() + ipAddr);
            return WebResult.failure("验证码错误");
        }
        user.setPassword(SecureUtil.md5(user.getPassword()));
        save(user);
        return WebResult.success("操作成功");
    }

    @Override
    public List<User> getUserByIds(Set<Integer> parts) {
        List<User> list = new ArrayList<>();
        if (parts != null && parts.size() > 0) {
            list = listByIds(parts);
        }
        return list;
    }

    @Override
    public Map<Long, String> getUserNickNameMapByIds(Set<Integer> parts) {
        Map<Long, String> map = new HashMap<>();
        if (parts != null && parts.size() > 0) {
            List<User> userList = listByIds(parts);
            map = userList.stream().collect(Collectors.toMap(User::getId, User::getNickName));
        }
        return map;
    }

    @Override
    public User dtl(Integer id) {
        User user = getById(id);
        ArrayList<User> list = new ArrayList<>();
        list.add(user);
        getText(list);
        return list.get(0);
    }

    @Override
    public WebResult delete(String id) {
        removeById(id);

        return WebResult.success("操作成功");
    }

    private void getText(List<User> records) {
        if (ArrayUtil.isNotEmpty(records) && records.size() > 0) {
            // 获取中文 所属项目 用户角色
            Map<Integer, String> roleNameMap = roleService.getAllRoleNameMap();
            Map<String, String> projectNameMap = projectService.getAllProjectNameMap();
            records.stream().forEach(a -> {
                a.setRoleText(roleNameMap.get(a.getRoleId()));
                a.setProjectText(projectNameMap.get(a.getProjectId()));
            });
        }
    }
}
